//---------------------------------------------------------------------------------
// Copyright (c) 2011, Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//---------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.ServiceBus.Description;

namespace Microsoft.Samples.DuplicateDetection
{
    class Program
    {
        static void Main()
        {
            string queueNameDupDection = "RemoveDuplicatesQueue";
            string queueNameNoDupDection = "DefaultQueue";

            NamespaceManager namespaceManager;
            MessagingFactory messagingFactory;
            string serviceNamespace, issuerName, issuerKey;

            // Read user credentials
            Console.Write("ServiceBus Namespace: ");
            serviceNamespace = Console.ReadLine();
            Console.Write("ServiceBus Issuer Name: ");
            issuerName = Console.ReadLine();
            Console.Write("ServiceBus Issuer Secret: ");
            issuerKey = Console.ReadLine();
            Console.WriteLine();

            // Get ServiceBusNamespaceClient for management operations
            namespaceManager = GetNamespaceManager(serviceNamespace, issuerName, issuerKey);

            // 1. Create a queue without duplicate detection enabled
            Console.WriteLine("\nCreating {0} ...", queueNameNoDupDection);
            if (namespaceManager.QueueExists(queueNameNoDupDection))
            {
                namespaceManager.DeleteQueue(queueNameNoDupDection);
            }
            namespaceManager.CreateQueue(queueNameNoDupDection);
            Console.WriteLine("Created {0}", queueNameNoDupDection);

            // Get messageFactory for runtime operation
            messagingFactory = GetMessagingFactory(serviceNamespace, issuerName, issuerKey);

            SendReceive(messagingFactory, queueNameNoDupDection);

            // 2. Create a queue with duplicate detection enabled
            Console.WriteLine("\nCreating {0} ...", queueNameDupDection);
            if (namespaceManager.QueueExists(queueNameDupDection))
            {
                namespaceManager.DeleteQueue(queueNameDupDection);
            }
            namespaceManager.CreateQueue(new QueueDescription(queueNameDupDection){RequiresDuplicateDetection = true});
            Console.WriteLine("Created {0}", queueNameDupDection);
            SendReceive(messagingFactory, queueNameDupDection);
            
            Console.WriteLine("\nPress [Enter] to exit.");
            Console.ReadLine();

            // Cleanup:
            namespaceManager.DeleteQueue(queueNameDupDection);
            namespaceManager.DeleteQueue(queueNameNoDupDection);
        }

        // Get ServiceBusNamespaceClient for management operations
        static NamespaceManager GetNamespaceManager(string serviceNamespace, string issuerName, string issuerKey)
        {
            Uri managementUri = ServiceBusEnvironment.CreateServiceUri("https", serviceNamespace, string.Empty);

            // Create the queue with duplicate detection enabled
            return new NamespaceManager(
                managementUri,
                TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerKey));
        }

        // Get messageFactory for runtime operation
        static MessagingFactory GetMessagingFactory(string serviceNamespace, string issuerName, string issuerKey)
        {
            Uri runtimeUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, string.Empty);

            return MessagingFactory.Create(
                runtimeUri,
                TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerKey));
        }

        static void SendReceive(MessagingFactory messagingFactory, string queueName)
        {
            QueueClient queueClient = messagingFactory.CreateQueueClient(queueName);

            // Send messages to queue
            Console.WriteLine("\tSending messages to {0} ...", queueName);
            BrokeredMessage message = new BrokeredMessage();
            message.MessageId = "ABC123";
            queueClient.Send(message);
            Console.WriteLine("\t=> Sent a message with messageId {0}", message.MessageId);

            BrokeredMessage message2 = new BrokeredMessage();
            message2.MessageId = "ABC123";
            queueClient.Send(message2);
            Console.WriteLine("\t=> Sent a duplicate message with messageId {0}", message.MessageId);

            // Receive messages from queue
            string receivedMessageId = "";

            Console.WriteLine("\n\tWaiting for messages from {0} ...", queueName);
            while (true)
            {
                BrokeredMessage receivedMessage = queueClient.Receive(TimeSpan.FromSeconds(10));

                if (receivedMessage == null)
                {
                    break;
                }
                else
                {
                    Console.WriteLine("\t<= Received a message with messageId {0}", receivedMessage.MessageId);
                    receivedMessage.Complete();
                    if (receivedMessageId.Equals(receivedMessage.MessageId, StringComparison.OrdinalIgnoreCase))
                    {
                        Console.WriteLine("\t\tRECEIVED a DUPLICATE MESSAGE");
                    }

                    receivedMessageId = receivedMessage.MessageId;
                }
            }

            Console.WriteLine("\tDone receiving messages from {0}", queueName);

            queueClient.Close();
        }
    }
}
